package com.lyEducation.repository;

import org.hibernate.transform.ResultTransformer;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.sql.Timestamp;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public interface AbstractPersisTableRepository<I> extends IDTypeService<I> {

  EntityManager getEntityManager();

  <T> T save(T entity);

  <T> T update(T entity);

  <T> T findById(Class<T> clazz, I id);

  /**
   * 根据表名，字段，参数查询，拼接sql语句
   *
   * @param clazz 表实体
   * @param filed 字段名
   * @param o 字段参数
   * @return
   */
  <T> List<T> findByFiled(Class<T> clazz, String filed, Object o);

  /**
   * 多个字段的查询
   *
   * @param clazz 表实体
   * @param linkedHashMap 将你的字段传入map中
   * @return
   */
  <T> List<T> findByFileds(Class<T> clazz, LinkedHashMap<String, Object> linkedHashMap);

  <T> List<T> findAll(Class<T> clazz);

  /** 不分页 */
  <T> List<T> findByNativeQuery(
      String sql, Map<String, Object> conditionParams, ResultTransformer resultTransformer);

  /**
   * 一个字段的分页
   *
   * @param clazz 表实体
   * @param filed 字段名
   * @param o 字段参数
   * @param pageNo 第几页
   * @param pageSize 一个页面多少条数据
   * @return
   */
  <T> List<T> findPageByNativeQueryFiled(
      Class<T> clazz, String filed, Object o, int pageNo, int pageSize);

  /**
   * 多字段查询分页
   *
   * @param pageNo 第几页
   * @param pageSize 一个页面的条数
   * @param resultTransformer Transformer.
   * @param conditionParams
   * @return
   */
  Map<String, Object> findPageByNativeQueryFileds(
      String sql,
      Map<String, Object> conditionParams,
      ResultTransformer resultTransformer,
      Integer pageNo,
      Integer pageSize);

  /**
   *
   * @param clazz
   * @param sql
   * @param conditionParams
   * @param valueParams
   * @param <T>
   * @return
   */
  <T> Integer updateFileds(Class<T> clazz, String hql,
                           Map<String, Object> conditionParams, Map<String, Object> valueParams);

  /**
   * 只能删除持久状态的实体
   *
   * @param entity
   */
  <T> boolean remove(T entity);

  /**
   * 根据表的id删除数据
   *
   * @param clazz
   */
  <T> boolean deleteById(Class<T> clazz, I id);

  /**
   * 根据参数删除表数据
   *
   * @param clazz
   */
  <T> boolean deleteByMap(Class<T> clazz, Map paramsMap);

  /**
   * 根据参数删除表数据
   *
   * @param clazz
   */
  <T> boolean deleteByMap(Class<T> clazz, String hql, Map<String, Object> paramsMap);

  /**
   * 根据id查询
   *
   * @param t
   * @param idClass
   * @return
   */
  <T> T findByIdClass(T t, Object idClass);


  /**
   * 添加俩个实体关联的中间表实体
   *
   * @param clazz
   * @param primaryKeyName1
   * @param primaryKeyValue1
   * @param primaryKeyName2
   * @param primaryKeyValue2
   * @param createTime
   * @param <MT>
   * @return
   */
  <MT> boolean addMiddleTable(
      Class<MT> clazz,
      String primaryKeyName1,
      String primaryKeyValue1,
      String primaryKeyName2,
      String primaryKeyValue2,
      Timestamp createTime);

  <MT> MT findMiddleTable(
      Class<MT> clazz,
      String primaryKeyName1,
      String primaryKeyValue1,
      String primaryKeyName2,
      String primaryKeyValue2);

  <MT> boolean delMiddleTable(
      Class<MT> clazz,
      String primaryKeyName1,
      String primaryKeyValue1,
      String primaryKeyName2,
      String primaryKeyValue2);

  <MT> boolean updMiddleTable(
      Class<MT> clazz,
      String primaryKeyName1,
      String primaryKeyValue1,
      String primaryKeyName2,
      String primaryKeyValue2);

  // ---------------------------------first
  <T> T first(TypedQuery<T> tqSelect);

  <T> T first(Class<T> clazz, String hql);

  <T> T first(Class<T> clazz, String hql, Object arg);

  <T> T first(Class<T> clazz, String hql, Object arg, Object arg2);

  <T> T first(Class<T> clazz, String hql, Object... args);

  // ---------------------------------single
  <T> T single(Class<T> clazz, String hql);

  <T> T single(Class<T> clazz, String hql, Object arg);

  <T> T single(Class<T> clazz, String hql, Object arg, Object arg2);

  <T> T single(Class<T> clazz, String hql, Object... args);

  // ---------------------------------list
  <T> List<T> list(Class<T> clazz, String hql);

  <T> List<T> list(Class<T> clazz, String hql, Object arg);

  <T> List<T> list(Class<T> clazz, String hql, Object arg, Object arg2);

  <T> List<T> list(Class<T> clazz, String hql, Object... args);

  // ---------------------------------top
  <T> List<T> top(int top, Class<T> clazz, String hql);

  <T> List<T> top(int top, Class<T> clazz, String hql, Object arg);

  <T> List<T> top(int top, Class<T> clazz, String hql, Object arg, Object arg2);

  <T> List<T> top(int top, Class<T> clazz, String hql, Object... args);
}
